package com.googlecode.wicketcharts.highcharts.gson;

import java.awt.Color;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.googlecode.wicketcharts.highcharts.options.AxisType;
import com.googlecode.wicketcharts.highcharts.options.Center;
import com.googlecode.wicketcharts.highcharts.options.Cursor;
import com.googlecode.wicketcharts.highcharts.options.GridLineDashStyle;
import com.googlecode.wicketcharts.highcharts.options.HorizontalAlignment;
import com.googlecode.wicketcharts.highcharts.options.LegendLayout;
import com.googlecode.wicketcharts.highcharts.options.Overflow;
import com.googlecode.wicketcharts.highcharts.options.PixelOrPercent;
import com.googlecode.wicketcharts.highcharts.options.SeriesType;
import com.googlecode.wicketcharts.highcharts.options.Stacking;
import com.googlecode.wicketcharts.highcharts.options.Symbol;
import com.googlecode.wicketcharts.highcharts.options.TickPosition;
import com.googlecode.wicketcharts.highcharts.options.TickmarkPlacement;
import com.googlecode.wicketcharts.highcharts.options.VerticalAlignment;
import com.googlecode.wicketcharts.highcharts.options.ZoomType;

/**
 * Factory for {@link Gson} objects to be used by the Highcharts abstraction for
 * translation into JSON.
 * 
 * @author Tom Hombergs (tom.hombergs@gmail.com)
 * 
 */
public class GsonFactory {

	private static GsonBuilder gsonBuilder;

	/**
	 * With this method, you can define your own {@link GsonBuilder}. The
	 * {@link GsonBuilder} you provide here will be used by wicket-charts to
	 * serialize the charts options into JSON. Thus, you can customize how GSON
	 * serializes the objects. For example, you can do the following things with
	 * your own GsonBuilder:
	 * <ul>
	 * <li>Enable pretty printing via builder.setPrettyPrinting().</li>
	 * <li>Register your own GSON type adapters via
	 * builder.registerTypeAdapter() to customize serializing. This may be
	 * needed if you extend the options-classes and add your own attributes to
	 * be serialized./li>
	 * </ul>
	 * 
	 * @param builder
	 *            the {@link GsonBuilder} to use for JSON serialization.
	 */
	public static void setGsonBuilder(GsonBuilder builder) {
		gsonBuilder = builder;
	}

	/**
	 * Returns a {@link GsonBuilder} to serialize Java objects into JSON. Will
	 * use the {@link GsonBuilder} provided by
	 * {@link #setGsonBuilder(GsonBuilder)} or create a new one, if none was
	 * specified.
	 * 
	 * @return a {@link Gson} object to be used for JSON serialization.
	 */
	public static Gson createGson() {
		GsonBuilder builder = gsonBuilder;
		if (builder == null) {
			builder = new GsonBuilder();
		}

		GsonLowercaseEnumSerializer lowercaseEnumSerializer = new GsonLowercaseEnumSerializer();

		builder.registerTypeAdapter(AxisType.class, lowercaseEnumSerializer);
		builder.registerTypeAdapter(SeriesType.class, lowercaseEnumSerializer);
		builder.registerTypeAdapter(HorizontalAlignment.class,
				lowercaseEnumSerializer);
		builder.registerTypeAdapter(VerticalAlignment.class,
				lowercaseEnumSerializer);
		builder.registerTypeAdapter(ZoomType.class, lowercaseEnumSerializer);
		builder.registerTypeAdapter(LegendLayout.class, lowercaseEnumSerializer);
		builder.registerTypeAdapter(Cursor.class, lowercaseEnumSerializer);
		builder.registerTypeAdapter(Stacking.class, lowercaseEnumSerializer);
		builder.registerTypeAdapter(Overflow.class, lowercaseEnumSerializer);
		builder.registerTypeAdapter(GridLineDashStyle.class,
				lowercaseEnumSerializer);
		builder.registerTypeAdapter(TickPosition.class, lowercaseEnumSerializer);
		builder.registerTypeAdapter(TickmarkPlacement.class,
				lowercaseEnumSerializer);
		builder.registerTypeAdapter(Color.class, new GsonColorSerializer());
		builder.registerTypeAdapter(Symbol.class, new GsonSymbolSerializer());
		builder.registerTypeAdapter(Center.class, new GsonCenterSerializer());
		builder.registerTypeAdapter(PixelOrPercent.class, new GsonPixelOrPercentSerializer());
		return builder.create();
	}
}
